package com.google.code.p.localspinner.yahoo;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URLEncoder;
import java.text.MessageFormat;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;

import com.google.code.p.localspinner.AppUtils;
import com.google.code.p.localspinner.SearchException;
import com.google.code.p.localspinner.http.UserAgent;
import com.google.code.p.localspinner.model.Item;
import com.google.code.p.localspinner.model.ItemList;

public class LocalSearcher {

  private UserAgent userAgent = new UserAgent();
  private final XmlPullParser pullParser;
  private static final String BASE_QUERY = 
  "http://local.yahooapis.com/LocalSearchService/V2/localSearch?appid=uDJx9qrV34EBGfuph_xY1AnWYLp1zzu.v2e7lag5lrwgyI152VkMCFhD2Uvglf24bA--&query={0}&location={1}&results=12";
  
  public LocalSearcher() throws SearchException{
    try {
      pullParser = XmlPullParserFactory.newInstance().newPullParser();
    } catch (XmlPullParserException e) {
      throw new SearchException("Unable to initialize xml parser", e);
    }
  }
  
  public ItemList search(String query, String location) throws SearchException{
    String url = MessageFormat.format(BASE_QUERY, URLEncoder.encode(query), URLEncoder.encode(location));
    InputStream res = null;
    try {
      res = userAgent.getUrlAsStream(url);
      pullParser.setInput(new InputStreamReader(res));
      return parseResult(pullParser);
    } catch (Exception e) {
      throw new SearchException("Search failed", e);
    }finally{
      AppUtils.closeQuietly(res);
    }
  }
  
  private ItemList parseResult(XmlPullParser pullParser) throws XmlPullParserException, IOException{
    ItemList ret = new ItemList();
    int eventType = pullParser.getEventType();
    while(eventType != XmlPullParser.END_DOCUMENT){
      if(eventType == XmlPullParser.START_TAG){
          if("Result".equalsIgnoreCase(pullParser.getName())){
            String title = null;
            StringBuilder body = new StringBuilder();
            String url = null;
            //children of Result
            while(true){
                if(eventType == XmlPullParser.END_TAG && "Result".equalsIgnoreCase(pullParser.getName())){
                    break;
                }
                eventType = pullParser.next(); 
                if(eventType == XmlPullParser.START_TAG){
                  String name = pullParser.getName();
                  if("Title".equalsIgnoreCase(name)){
                    eventType = pullParser.next();
                    if(eventType == XmlPullParser.TEXT){
                      title = AppUtils.nvl(pullParser.getText(), "");
                    }
                  }else if("Address".equalsIgnoreCase(name)
                      || "City".equalsIgnoreCase(name)
                      || "State".equalsIgnoreCase(name)){
                    eventType = pullParser.next();
                    if(eventType == XmlPullParser.TEXT){
                      body.append(AppUtils.nvl(pullParser.getText()+" ", ""));
                    }
                  }else if("Phone".equalsIgnoreCase(name)){
                    eventType = pullParser.next();
                    if(eventType == XmlPullParser.TEXT){
                      body.append(AppUtils.nvl("\n"+pullParser.getText(), ""));
                    }
                  }else if("ClickUrl".equalsIgnoreCase(name)){
                    eventType = pullParser.next();
                    if(eventType == XmlPullParser.TEXT){
                      url = AppUtils.nvl(pullParser.getText(), "");
                    }
                  }                  
                }
                eventType = pullParser.next();
            }
            if(title != null){
              Item item = new Item(title, body.toString());
              item.setUrl(url);
              ret.addItem(item);
            }
          }
      }
      eventType = pullParser.next();
    }
    return ret;
  }
 
}
